package com.ndd.service.impl;

import com.ndd.constant.Constants;
import com.ndd.dto.*;
import com.ndd.entity.User;
import com.ndd.enums.ServiceCode;
import com.ndd.exception.ServiceException;
import com.ndd.mapper.UserMapper;
import com.ndd.service.UserService;
import com.ndd.utils.JwtUtils;
import com.ndd.utils.MD5Utils;
import com.ndd.vo.UserLoginVO;
import com.ndd.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * @ProjectName: cmall-ybu
 * @Titile: UserServiceImpl
 * @Author: Lucky
 * @Description: 用户业务实现类
 */
@Service //业务层
@Slf4j
@Transactional //事务
public class UserServiceImpl implements UserService {
    //注入持久层
    @Autowired
    private UserMapper userMapper;
    @Override
    public void register(RegisterDTO registerDTO) {
        //判断密码与重复密码是否一致
        if(!registerDTO.getPassword().equals(registerDTO.getRePassword())){
           throw new ServiceException(ServiceCode.ERR_BAD_REQUEST,"两次输入的密码不一致");
        }
        //生成salt
        String salt = UUID.randomUUID().toString().replace("-","");
        // 对密码进行加密
        String password = MD5Utils.enctype(registerDTO.getPassword(), salt, Constants.HASH_TIME);
        log.debug("密码加密后：{}",password);
        log.debug("salt：{}",salt);
        //封装user
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        //使用加密后的密码
        user.setPassword(password);
        user.setSalt(salt);
        user.setIsDelete(Constants.IS_NOT_DELETE);
        user.setCreatedUser(registerDTO.getUsername());
        //调用持久层进行新增用户
        int result = userMapper.insert(user);
        if(result != 1){
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED,"注册用户失败");
        }
    }

    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        //根据用户名去查询用户
        User user = userMapper.getByName(userLoginDTO.getUsername());
        if(user==null || user.getUsername()==null){
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,"登录的用户名不存在");
        }
        //判断是否被锁定
        if(user.getIsDelete()==1){
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN,"该账户被锁定");
        }
        //判断密码
        //将登录密码进行加密
        String password = MD5Utils.enctype(userLoginDTO.getPassword(), user.getSalt(), Constants.HASH_TIME);
        if(!password.equals(user.getPassword())){
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN,"密码错误");
        }
        // 用户登录成功，保证逻辑的粒度
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setId(user.getId());
        userLoginVO.setUsername(user.getUsername());
        //生成token
        String token = JwtUtils.generateToken(userLoginVO);
        userLoginVO.setToken(token);
        return userLoginVO;
    }

    /**
     * 修改用户信息
     */
    @Override
    public void updateUser(UserUpdateDTO userUpdateDTO, UserLoginVO userLoginVO) {
        //将数据封装到user实体类中
        User user = new User();
        user.setUsername(userUpdateDTO.getUsername());
        user.setPhone(userUpdateDTO.getPhone());
        user.setEmail(userUpdateDTO.getEmail());
        user.setGender(userUpdateDTO.getGender());
        user.setId(userLoginVO.getId());
        //操作数据库进行修改数据
        userMapper.updateUser(user);
    }

    /**
     * 修改密码
     * @param userUpdatePwdDTO 修改的密码信息
     * @param userLoginVO 修改人信息
     */
    @Override
    public void updatePwd(UserUpdatePwdDTO userUpdatePwdDTO, UserLoginVO userLoginVO) {
        //校验新密码与确认密码是否一致
        if(!userUpdatePwdDTO.getNewPwd().equals(userUpdatePwdDTO.getReNewPwd())){
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST,"两次输入的密码不一致");
        }
        /*判断原来密码
            根据登录用户的身份（username），去查询数据库，得到一个用户对象，判断密码
         */
        User user = userMapper.getByName(userLoginVO.getUsername());
        //将原来密码加密
        String password = MD5Utils.enctype(userUpdatePwdDTO.getOldPwd(),user.getSalt(),Constants.HASH_TIME);
        if(!password.equals(user.getPassword())){
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN,"没有权限修改密码");
        }
        //旧密码与数据库的密码匹配上
        //获取盐值
        String salt = UUID.randomUUID().toString().replace("-","");
        //重新加密
        String newPwd = MD5Utils.enctype(userUpdatePwdDTO.getNewPwd(), salt, Constants.HASH_TIME);
        //构建用户信息
        user = new User();
        user.setPassword(newPwd);
        user.setSalt(salt);
        user.setModifiedUser(userLoginVO.getUsername());
        //封装修改条件
        user.setId(userLoginVO.getId());
        //修改
        int result = userMapper.updatePwd(user);
        if(result != 1){
            throw new ServiceException(ServiceCode.ERR_UPDATE_FAILED,"修改密码失败");
        }

    }

    /**
     * 根据id查询用户信息
     * @return
     */
    @Override
    public UserVO selectById(Integer id) {
        UserVO userVO = userMapper.selectById(id);
        return userVO;
    }

    /**
     * 处理头像上传的业务
     * @param avatar 头像
     * @param userLoginVO 上传人
     */
    @Override
    public void upload(MultipartFile avatar, UserLoginVO userLoginVO) {
        //设置头像上传的路径
        String savePath = System.getProperty("user.dir")+
                File.separator+"market-server" +
                File.separator+"src"+File.separator+"main"+
                File.separator+"resources"+File.separator+"images";
        //获取文件名
        String filename = avatar.getOriginalFilename();
        //截取后缀拼接新的名称
        filename = UUID.randomUUID().toString().replace("-","")
                +filename.substring(filename.lastIndexOf("."));
        //创建父目录+文件
        File parentFile = new File(savePath,filename);
        try {
            //上传文件
            avatar.transferTo(parentFile);
        } catch (IOException e) {
            throw new ServiceException(ServiceCode.ERR_FILE_UPLOAD,"文件上传失败");
        }
        //修改数据中用户的头像地址
        // 创建用户对象
        User user = new User();
        user.setId(userLoginVO.getId());
        user.setAvatar(filename);
        user.setModifiedUser(userLoginVO.getUsername());
        //调用持久层进行数据持久化操作
        int result = userMapper.setAvatar(user);
        if(result != 1){
            //手动设置事务
            //手动去删除这张图片
            boolean delete = parentFile.delete();
            if(!delete){
                log.debug("由于数据库设置头像失败，需要删除头像：{}",filename);
            }
            throw new ServiceException(ServiceCode.ERR_UPDATE_FAILED,"设置头像失败");
        }
    }
    //删除购物车
    @Override
    public void deletCart(@RequestBody deletCartDTO deletcartDTO, UserLoginVO userLoginVO){
        int[] productid=deletcartDTO.getProductid();
        System.out.println(userLoginVO.getId());
        log.debug("usvo{}",userLoginVO);
        for (int item : productid) {
            int result= userMapper.deletCart(item,userLoginVO.getId());
            if (result ==0){
                throw new ServiceException(ServiceCode.ERR_UPDATE_FAILED,"删除失败");
            }
        }





    }








}
